#include <windows.h>
#include <hidsdi.h>
#include <SetupAPI.h>
#include <stdio.h>
#include <stdlib.h>  // 添加标准库头文件
#include <string.h>  // 添加字符串操作头文件
#include <wchar.h>   // 添加宽字符支持
#include <wctype.h>  // 添加宽字符类型函数
#include <ctype.h>   // 添加字符类型函数
#include <time.h>    // 添加时间函数
#include "headset.h"
#include "logger.h"

// 支持多个耳机设备定义
typedef struct {
    USHORT vid;
    USHORT pid;
    char* name;
    int protocol_type; // 协议类型：0=标准，1=华为，2=苹果，等等
} HeadsetDevice;

// 已知支持的耳机设备列表
static const HeadsetDevice known_devices[] = {
    {0x12D1, 0x3A07, "Huawei Headset", 1},   // 华为耳机
    {0x05AC, 0x12A8, "Apple Headset", 2},    // 苹果耳机示例
    {0x046D, 0x0A38, "Logitech Headset", 0}, // 罗技耳机示例
    {0x1532, 0x0504, "Razer Headset", 0},    // 雷蛇耳机示例
    {0x045E, 0x070F, "Microsoft Headset", 0} // 微软耳机示例
    // 可以继续添加更多设备
};

#define NUM_KNOWN_DEVICES (sizeof(known_devices) / sizeof(HeadsetDevice))
// 当前设备的协议类型
static int current_protocol_type = 0;

// 不同协议的按键定义
// 标准协议
#define STD_KEY_NONE        0x00
#define STD_KEY_VOLINC      0x01
#define STD_KEY_VOLDDEC     0x02
#define STD_KEY_PLAYPAUSE   0x04
#define STD_KEY_NEXT        0x08
#define STD_KEY_PREV        0x10

// 华为协议
#define HUAWEI_KEY_NONE        0x00
#define HUAWEI_KEY_VOLINC      0x01
#define HUAWEI_KEY_VOLDDEC     0x02
#define HUAWEI_KEY_PLAYPAUSE   0x04

// 苹果协议
#define APPLE_KEY_NONE        0x00
#define APPLE_KEY_VOLINC      0x01
#define APPLE_KEY_VOLDDEC     0x02
#define APPLE_KEY_PLAYPAUSE   0x04
#define APPLE_KEY_NEXT        0x08
#define APPLE_KEY_PREV        0x10

// 新增超时和双击检测常量
#define WAIT_TIMEOUT_MS      200  // 等待超时时间(毫秒)
#define DOUBLECLICK_TIME_MS  200  // 双击时间阈值(毫秒)
// 添加按键重复触发相关常量
#define KEY_REPEAT_DELAY_MS  500  // 首次重复延迟(毫秒)
#define KEY_REPEAT_RATE_MS   100  // 重复速率(毫秒)

// 查找并打开headset设备
static HANDLE open_headset_input_device() {
    GUID hidGuid;
    HidD_GetHidGuid(&hidGuid);  // 获取 HID 接口的 GUID    
    HDEVINFO deviceInfoSet = SetupDiGetClassDevs(&hidGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
    if (deviceInfoSet == INVALID_HANDLE_VALUE) return NULL;

    SP_DEVICE_INTERFACE_DATA interfaceData = { .cbSize = sizeof(SP_DEVICE_INTERFACE_DATA) };
    DWORD index = 0;
    HANDLE deviceHandle = NULL;

    while (SetupDiEnumDeviceInterfaces(deviceInfoSet, NULL, &hidGuid, index++, &interfaceData)) {
        DWORD requiredSize = 0;
        SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &interfaceData, NULL, 0, &requiredSize, NULL);

        PSP_DEVICE_INTERFACE_DETAIL_DATA detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(requiredSize);
        if (detailData == NULL) {
            SetupDiDestroyDeviceInfoList(deviceInfoSet);
            return NULL;
        }
        detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

        SP_DEVINFO_DATA deviceData = { .cbSize = sizeof(SP_DEVINFO_DATA) };
        if (SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &interfaceData, detailData, requiredSize, NULL, &deviceData)) {
            // 打开设备
            deviceHandle = CreateFile(
                detailData->DevicePath,
                GENERIC_READ | GENERIC_WRITE,
                FILE_SHARE_READ | FILE_SHARE_WRITE,
                NULL,
                OPEN_EXISTING,
                FILE_FLAG_OVERLAPPED,
                NULL
            );

            if (deviceHandle != INVALID_HANDLE_VALUE) {
                // 检查设备属性以确认是否为目标设备
                HIDD_ATTRIBUTES attributes = { .Size = sizeof(HIDD_ATTRIBUTES) };
                if (HidD_GetAttributes(deviceHandle, &attributes)) {
                    dlog("Headset: HID device VID=0x%04X, PID=0x%04X\n", attributes.VendorID, attributes.ProductID);
                    
                    // 检查是否为已知设备
                    for (int i = 0; i < NUM_KNOWN_DEVICES; i++) {
                        if (attributes.VendorID == known_devices[i].vid && 
                            attributes.ProductID == known_devices[i].pid) {
                            ilog("  supported headset: %s\n", known_devices[i].name);
                            current_protocol_type = known_devices[i].protocol_type;
                            free(detailData);
                            SetupDiDestroyDeviceInfoList(deviceInfoSet);
                            return deviceHandle;
                        }
                    }
                    
                    // 尝试检测通用音频设备特征
                    BOOL isGenericAudio = FALSE;
                    
                    // 使用HidD_GetProductString等函数获取更多设备信息
                    WCHAR productString[126] = {0};
                    if (HidD_GetProductString(deviceHandle, productString, sizeof(productString))) {
                        // 检查产品名称是否包含"headset"、"earphone"等关键词
                        dlog("  product String: %ls\n", productString);
                        WCHAR lowerCase[126] = {0};
                        
                        // 使用标准C库函数复制字符串
                        wcsncpy(lowerCase, productString, 125);
                        lowerCase[125] = L'\0'; // 确保字符串以null结尾
                        
                        // 使用标准C库函数转换为小写
                        for (WCHAR *p = lowerCase; *p; ++p) {
                            *p = towlower(*p);
                        }
                        
                        // 使用标准C库函数查找子字符串
                        if (wcsstr(lowerCase, L"headset") || 
                            wcsstr(lowerCase, L"earphone") ||
                            wcsstr(lowerCase, L"headphone") ||
                            wcsstr(lowerCase, L"audio")) {
                            isGenericAudio = TRUE;
                            current_protocol_type = 0; // 使用标准协议
                        }
                    }
                    
                    if (isGenericAudio) {
                        ilog("  %ls: generic audio device\n", productString);
                        free(detailData);
                        SetupDiDestroyDeviceInfoList(deviceInfoSet);
                        return deviceHandle;
                    }
                    dlog("  not a supported headset device\n");
                }
                CloseHandle(deviceHandle);
            }
        }
        free(detailData);
    }
    SetupDiDestroyDeviceInfoList(deviceInfoSet);
    return NULL;
}

// 解析按键事件，根据不同协议
static HeadsetButton parse_button_event(BYTE* buffer, DWORD bytesRead) {
    HeadsetButton button = BUTTON_NONE;
    
    // 基本数据验证
    if (!buffer || bytesRead < 1) {
        return BUTTON_NONE;
    }
    
    // 获取Report ID（通常是第一个字节）
    BYTE reportId = buffer[0];
    BYTE* dataBytes = buffer + 1;  // 跳过Report ID
    DWORD dataLength = bytesRead - 1;
    
    switch (current_protocol_type) {
        case 0: // 标准协议
            if (dataLength >= 1 /*&& (reportId == 0x01 || reportId == 0x02 || reportId == 0x03)*/) {
                BYTE keyData = dataBytes[0];
                // 优先级检查，避免同时触发多个按键
                if (keyData & STD_KEY_VOLINC) return BUTTON_VOLINC;
                if (keyData & STD_KEY_VOLDDEC) return BUTTON_VOLDDEC;
                if (keyData & STD_KEY_PLAYPAUSE) return BUTTON_PLAYPAUSE;
                if (keyData & STD_KEY_NEXT) return BUTTON_NEXT;
                if (keyData & STD_KEY_PREV) return BUTTON_PREV;
            }
            break;
            
        case 1: // 华为协议
            if (dataLength >= 1 /*&& (reportId == 0x01 || reportId == 0x02)*/) {
                BYTE keyData = dataBytes[0];
                if (keyData & HUAWEI_KEY_VOLINC) return BUTTON_VOLINC;
                if (keyData & HUAWEI_KEY_VOLDDEC) return BUTTON_VOLDDEC;
                if (keyData & HUAWEI_KEY_PLAYPAUSE) return BUTTON_PLAYPAUSE;
            }
            break;
            
        case 2: // 苹果协议
            if (dataLength >= 1 /*&& (reportId == 0x03 || reportId == 0x04 || reportId == 0x01)*/) {
                BYTE keyData = dataBytes[0];
                if (keyData & APPLE_KEY_VOLINC) return BUTTON_VOLINC;
                if (keyData & APPLE_KEY_VOLDDEC) return BUTTON_VOLDDEC;
                if (keyData & APPLE_KEY_PLAYPAUSE) return BUTTON_PLAYPAUSE;
                if (keyData & APPLE_KEY_NEXT) return BUTTON_NEXT;
                if (keyData & APPLE_KEY_PREV) return BUTTON_PREV;
            }
            break;
            
        default:
            // 未知协议，尝试通用解析
            if (dataLength >= 1) {
                // 尝试多种可能的数据位置和格式
                for (DWORD i = 0; i < dataLength && i < 3; i++) {
                    BYTE data =  dataBytes[i];
                    
                    // 位模式检测
                    if (data == 0x01) return BUTTON_VOLINC;
                    if (data == 0x02) return BUTTON_VOLDDEC;
                    if (data == 0x04) return BUTTON_PLAYPAUSE;
                    if (data == 0x08) return BUTTON_NEXT;
                    if (data == 0x10) return BUTTON_PREV;
                }
            }
            break;
    }
    
    return button;
}

// 获取耳机按键事件
#define LOG_DEVICE_NOT_FOUND_RATE_MS 300000 // 设备未找到时的重试间隔 10s
HeadsetButton get_headset_button(void) {
    HANDLE deviceHandle = open_headset_input_device();
    if (!deviceHandle) {
        static DWORD lastLogTime = 0; // 上次日志记录时间
        DWORD currentTime = GetTickCount();
        // 如果设备未找到，且距离上次日志记录超过指定时间 ，则记录日志
        if (currentTime - lastLogTime > LOG_DEVICE_NOT_FOUND_RATE_MS) {
            lastLogTime = currentTime; // 更新上次日志记录时间
            ilog("Headset: device not found\n");
        }
        Sleep(WAIT_TIMEOUT_MS); // 等待一段时间后重试
        return BUTTON_NONE;
    }

    // 准备读取输入报告
    BYTE buffer[64];
    memset(buffer, 0, sizeof(buffer)); // 使用标准C库函数初始化内存
    
    DWORD bytesRead;
    OVERLAPPED overlapped = {0}; // 使用初始化为0
    overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    
    if (!overlapped.hEvent) {
        CloseHandle(deviceHandle);
        return BUTTON_NONE;
    }
    
    // 添加双击检测变量
    static DWORD lastPlayPauseTime = 0;
    static int playPauseClickCount = 0;
    // 添加音量按键状态跟踪变量
    static BOOL isVolIncPressed = FALSE;
    static BOOL isVolDecPressed = FALSE;
    static DWORD lastVolIncPressTime = 0;
    static DWORD lastVolDecPressTime = 0;
    // 添加长按检测变量
    static BOOL isLongPressDetected = FALSE;
    static DWORD pressStartTime = 0;
    #define LONG_PRESS_TIME_MS 1000  // 长按触发时间(毫秒)
    
    DWORD currentTime;
    HeadsetButton buttonPressed = BUTTON_NONE;
    DWORD waitTimeoutMs = INFINITE; // 设置超时时间
    
    while (1) {
        // 重置buffer
        memset(buffer, 0, sizeof(buffer));
        
        ReadFile(deviceHandle, buffer, sizeof(buffer), &bytesRead, &overlapped);
        
        // 使用超时参数
        if(isVolIncPressed || isVolDecPressed) {
            waitTimeoutMs = KEY_REPEAT_RATE_MS; // 设置超时为100毫秒
        } else if (playPauseClickCount > 0) {
            waitTimeoutMs = WAIT_TIMEOUT_MS; // 等待第二次点击
        } else {
            waitTimeoutMs = INFINITE;
        }
        
        DWORD waitResult = WaitForSingleObject(overlapped.hEvent, waitTimeoutMs);
        
        // 获取当前时间
        currentTime = GetTickCount();
        
        if (waitResult == WAIT_TIMEOUT) {
            // 超时处理代码 - 使用标准C库的条件判断
            // 检查是否需要触发音量键重复事件
            if (isVolIncPressed && 
                (currentTime - lastVolIncPressTime) > KEY_REPEAT_DELAY_MS &&
                (currentTime - lastVolIncPressTime) % KEY_REPEAT_RATE_MS < 20) {
                buttonPressed = BUTTON_VOLINC;
                break; // 使用break代替goto
            }
            
            if (isVolDecPressed && 
                (currentTime - lastVolDecPressTime) > KEY_REPEAT_DELAY_MS &&
                (currentTime - lastVolDecPressTime) % KEY_REPEAT_RATE_MS < 20) {
                buttonPressed = BUTTON_VOLDDEC;
                break; // 使用break代替goto
            }
            
            // 检查播放暂停双击
            if (playPauseClickCount == 1 && (currentTime - lastPlayPauseTime) > DOUBLECLICK_TIME_MS) {
                // 如果超过双击时间，认为是单击
                playPauseClickCount = 0;
                buttonPressed = BUTTON_PLAYPAUSE;
                break; // 使用break代替goto
            }
            
            // 检查长按
            if (pressStartTime > 0 && !isLongPressDetected && 
                (currentTime - pressStartTime) > LONG_PRESS_TIME_MS) {
                isLongPressDetected = TRUE;
                buttonPressed = BUTTON_PREV; // 长按通常映射为上一曲
                break; // 使用break代替goto
            }
            
            if(buttonPressed != BUTTON_NONE) 
                break; // 使用break代替goto
            else
                continue; // 如果没有按键被按下，则继续等待
        }

        if (GetOverlappedResult(deviceHandle, &overlapped, &bytesRead, TRUE)) {
            // 解析按键事件
            //ilog("Hid Received data: ");
            //for (DWORD i = 0; i < bytesRead; ++i) {
            //    printf("%02X ", buffer[i]);
            //}
            //printf("\n");
            
            // 使用通用解析函数处理不同设备的协议
            HeadsetButton button = parse_button_event(buffer, bytesRead);
            
            // 处理解析出的按键
            switch (button) {
                case BUTTON_VOLINC:
                    if (!isVolIncPressed) {
                        isVolIncPressed = TRUE;
                        lastVolIncPressTime = currentTime;
                    }
                    buttonPressed = BUTTON_VOLINC;
                    break; // 使用break和while循环中的条件判断
                    
                case BUTTON_VOLDDEC:
                    if (!isVolDecPressed) {
                        isVolDecPressed = TRUE;
                        lastVolDecPressTime = currentTime;
                    }
                    buttonPressed = BUTTON_VOLDDEC;
                    break; // 使用break和while循环中的条件判断
                    
                case BUTTON_PLAYPAUSE:
                    // 记录按下开始时间(用于长按检测)
                    if (pressStartTime == 0) {
                        pressStartTime = currentTime;
                    }
                    
                    // 检测是否为双击
                    if (playPauseClickCount > 0 && (currentTime - lastPlayPauseTime) < DOUBLECLICK_TIME_MS) {
                        // 是双击，重置计数器并返回NEXT
                        playPauseClickCount = 0;
                        pressStartTime = 0;
                        buttonPressed = BUTTON_NEXT;
                        break; // 使用break和while循环中的条件判断
                    } else {
                        // 记录第一次点击
                        playPauseClickCount = 1;
                        lastPlayPauseTime = currentTime;
                        waitTimeoutMs = WAIT_TIMEOUT_MS; // 设置下次等待超时
                    }
                    continue; // 继续等待可能的第二次点击
                    
                case BUTTON_NONE:
                    // 按键释放处理
                    isVolIncPressed = FALSE;
                    isVolDecPressed = FALSE;
                    
                    // 如果有按键释放，重置长按状态
                    if (pressStartTime > 0 && !isLongPressDetected) {
                        // 非长按释放
                        pressStartTime = 0;
                    }
                    isLongPressDetected = FALSE;
                    pressStartTime = 0;
                    continue;
                    
                default:
                    // 其他按键直接返回
                    buttonPressed = button;
                    break; // 使用break和while循环中的条件判断
            }
            
            if (buttonPressed != BUTTON_NONE) {
                break;  // 跳出循环
            }
        } else {
            ilog("Headset: read fail from device %d\n", GetLastError());
            break;
        }
    }

    // 清理资源
    CloseHandle(overlapped.hEvent);
    CloseHandle(deviceHandle);
    if(buttonPressed != BUTTON_NONE) {
        ilog("Headset: button %d pressed\n", buttonPressed);
    }
    return buttonPressed;
}

#ifdef TEST
int main() {
    while(1) {
        HeadsetButton button = get_headset_button();
        switch (button) {
            case BUTTON_VOLINC:
                printf("Volume Increase Button Pressed\n");
                break;
            case BUTTON_VOLDDEC:
                printf("Volume Decrease Button Pressed\n");
                break;
            case BUTTON_PLAYPAUSE:
                printf("Play/Pause Button Pressed\n");
                break;
            case BUTTON_NEXT:
                printf("Next Track Button Pressed\n");
                break;
            case BUTTON_PREV:
                printf("Previous Track Button Pressed\n");
                break;
            default:
                printf("No Button Pressed\n");
        }
    }
    return 0;
}
#endif // TEST